/* This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package Modelo;

import java.util.*;

import com.ice.jni.registry.*;

/**
 * Clase que representa una tecnica de busqueda de cadenas en los logs
 * @author Armando Machuca Llorente
 */
public class TecnicaReg extends Tecnica {

    /**
     * Constructor de la clase TenicaReg
     * @param tipo Tipo de tecnica:instalado o desinstalado
     * @param plugin Referencia al plugin que contiene la tecnica
     */
    public TecnicaReg(String tipo, Plugin plugin) {
        _param = new Vector<Parametro>();
        _tipo = tipo;
        _plugin = plugin;
    }

    /**
     * Metodo que permite ejecutar la tecnica
     * @param unidad Unidad sobre la que se realizara el analisis
     */
    public void ejecutar(String unidad) {

        _resultados = new Vector();
        if (getValue("tipo").compareTo("breg_ub") == 0) {
            buscarEnRegistro();
        }
        if (getValue("tipo").compareTo("breg_all") == 0) {
            buscarValorRegistro("", "HKEY_LOCAL_MACHINE", 1);
            buscarValorRegistro("", "HKEY_CLASSES_ROOT", 1);
            buscarValorRegistro("", "HKEY_CURRENT_USER", 1);
            buscarValorRegistro("", "HKEY_USERS", 1);
            buscarValorRegistro("", "HKEY_CURRENT_CONFIG", 1);
        }
        if (getValue("tipo").compareTo("breg_all_sec") == 0) {
            

            if (getValue("seccion").contains("\\")) {
                buscarValorRegistro(getValue("seccion"), "", 2);
            } else {
                buscarValorRegistro(getValue("seccion"), "", 1);
            }
        }
    }


    /*
     * El archivo DLL de este jar, hay que meterlo en la carpeta del proyecto
     * en la raiz solamente. a no se que se configure el java.lib, para que vaya
     * a la ruta que tu quieras a buscar la DLL
     */
    /**
     * Metodo que permite realizar una busqueda de un registro
     */
    public void buscarEnRegistro() {
        boolean resultado = false;
        String cl = getValue("registro");

        /* En primer lugar extraemos el nodo inicial de la clave tipo HKEY_LOCAL_MACHINE\\xx\xx */
        String raiz;
        String subclave;
        if (cl.charAt(0) != '\\') {
            raiz = cl.substring(0, cl.indexOf("\\", 1));
            subclave = cl.substring(cl.indexOf("\\", 1) + 1, cl.length());
        } else {
            raiz = cl.substring(1, cl.indexOf("\\", 2));
            subclave = cl.substring(cl.indexOf("\\", 2) + 1, cl.length());
        }

       




        /*
         * En este punto nos creamos un objeto que representa una Clave (nodo)
         * y con openSubkey le asignamos la ruta de la clave que queremos usar
         * y el arbol que vayamos a usar (el del user o el de la maquina local)
         * */


        RegistryKey regkey = null;

      

        if (raiz.compareTo("HKEY_LOCAL_MACHINE") == 0 || raiz.equalsIgnoreCase("HKLM") ) {
            regkey = Registry.HKEY_LOCAL_MACHINE;
        }
        if (raiz.compareTo("HKEY_CLASSES_ROOT") == 0) {
            regkey = Registry.HKEY_CLASSES_ROOT;
        }
        if (raiz.compareTo("HKEY_CURRENT_USER") == 0 || raiz.compareTo("HKCU") == 0) {
            regkey = Registry.HKEY_CURRENT_USER;
        }
        if (raiz.compareTo("HKEY_USERS") == 0) {
            regkey = Registry.HKEY_USERS;
        }
        if (raiz.compareTo("HKEY_CURRENT_CONFIG") == 0) {
            regkey = Registry.HKEY_CURRENT_CONFIG;
        }

        RegistryKey Clave = Registry.openSubkey(regkey, subclave, RegistryKey.ACCESS_ALL);

        try {
            /*Aqui nos creamos un objeto que representa un Registro y le asignamos
             * el registro que queremos sacado de la clve que nos creamos antes.
             * */
            //RegistryValue Registro = Clave.getValue("Dexpot");
            if (Clave != null) {
                resultado = true;
                String atributo = "";
                String valor = "";
                if (getValue("atributo") != null) {
                    if (getValue("atributo").length()>0){               
                    if (Clave.getStringValue(getValue("atributo")) != null) {
                        atributo = Clave.getValue(getValue("atributo")).getName();
                        if (Clave.getStringValue(Clave.getValue(getValue("atributo")).getName()) != null) {
                            valor = Clave.getStringValue(Clave.getValue(getValue("atributo")).getName());
                        }
                

                    atributo = Clave.getStringValue(Clave.getValue(getValue("atributo")).getName());
                    if (getValue("atributo").compareTo(atributo) == 0) {
                        resultado = true;
                    } else {
                        resultado = false;
                    }
                    }
                }
                    if (valor.length() > 0) {
                        if (getValue("valor").compareTo(valor) == 0) {
                            resultado = true;
                        } else {
                            resultado = false;
                        }
                    }
                }
            }
            if (resultado) {
                _resultados.add(new Parametro("registro", cl));
                if (getValue("atributo") != null) {
                    if (getValue("atributo").length()>0){
                    _resultados.add(new Parametro("atributo", Clave.getValue(getValue("atributo")).getName()));
                    }
                }
                if (getValue("valor") != null) {
                    if (getValue("valor").length()>0){
                    _resultados.add(new Parametro("valor", Clave.getStringValue(Clave.getValue(getValue("atributo")).getName())));
                    }
                }
                if (getResultado("encontrado").compareTo("true") != 0) {
                    _resultados.add(new Parametro("encontrado", "true"));
                }
            }
        } catch (Exception ex) {
            //En caso de no existir la clave referenciada por el plugin xml , se generara una excepcion. No se imprime porque no nos importa
            //ex.printStackTrace();
        }
    }

    /*
     * El archivo DLL de este jar, hay que meterlo en la carpeta del proyecto
     * en la raiz solamente. a no se que se configure el java.lib, para que vaya
     * a la ruta que tu quieras a buscar la DLL
     */
    /**
     * Metodo que permite buscar un valor en el registr
     * @param clave Clave donde se encuentra el valor
     * @param raiz Raiz desde donde se inicia la busqueda
     * @param iteracion Indica si la busqueda es recursiva
     */
    public void buscarValorRegistro(String clave, String raiz, int iteracion) {

        String cl = clave;
        //HAY QUE SEPARAR LA RAIZ DE LA CLAVE PARA BUSCAR POR SECCION
        if (raiz.trim().length() == 0 && cl.trim().length() > 0) {
            if (cl.charAt(0) != '\\') {
                raiz = cl.substring(0, cl.indexOf("\\", 1));
                clave = cl.substring(cl.indexOf("\\", 1) + 1, cl.length());
            } else {
                raiz = cl.substring(1, cl.indexOf("\\", 2));
                clave = cl.substring(cl.indexOf("\\", 2) + 1, cl.length());
            }
        }



        /* En primer lugar extraemos el nodo inicial de la clave tipo HKEY_LOCAL_MACHINE\\xx\xx */
        /*
         * En este punto nos creamos un objeto que representa una Clave (nodo)
         * y con openSubkey le asignamos la ruta de la clave que queremos usar
         * y el arbol que vayamos a usar (el del user o el de la maquina local)
         * */


        RegistryKey regkey = null;
        if (raiz.compareTo("HKEY_LOCAL_MACHINE") == 0 || raiz.equalsIgnoreCase("HKLM") ) {
            regkey = Registry.HKEY_LOCAL_MACHINE;
        }
        if (raiz.compareTo("HKEY_CLASSES_ROOT") == 0) {
            regkey = Registry.HKEY_CLASSES_ROOT;
        }
        if (raiz.compareTo("HKEY_CURRENT_USER") == 0 || raiz.compareTo("HKCU") == 0) {
            regkey = Registry.HKEY_CURRENT_USER;
        }
        if (raiz.compareTo("HKEY_USERS") == 0) {
            regkey = Registry.HKEY_USERS;
        }
        if (raiz.compareTo("HKEY_CURRENT_CONFIG") == 0) {
            regkey = Registry.HKEY_CURRENT_CONFIG;
        }

        RegistryKey Clave = Registry.openSubkey(regkey, clave, RegistryKey.ACCESS_ALL);

        try {
            /*Aqui nos creamos un objeto que representa un Registro y le asignamos
             * el registro que queremos sacado de la clve que nos creamos antes.
             * */
            //RegistryValue Registro = Clave.getValue("Dexpot");
            if (Clave != null) {

              
                Enumeration e = Clave.keyElements();
                String nueva_clave = "";
                while (e.hasMoreElements()) {
                    //RegistryKey r=(RegistryKey)e.nextElement();
                    RegistryKey sub = null;
                    try {
                        nueva_clave = (String) e.nextElement();
                    
                        if (iteracion == 2) {
                            sub = Registry.openSubkey(regkey, clave + "\\" + nueva_clave, RegistryKey.ACCESS_ALL);
                        }
                        if (iteracion == 1) {
                            sub = Registry.openSubkey(regkey, clave + nueva_clave, RegistryKey.ACCESS_ALL);
                        }
                    } catch (java.util.NoSuchElementException nsexc) {
                    }
                    if (sub != null) {

                        int defaultValue = sub.getNumberValues();
                      
                        Enumeration l = sub.valueElements();
                        //AQUI A COMPARAR CON TODOS LOS ELEMENTOS DE l
                        while (l.hasMoreElements()) {
                            String valueName = (String) l.nextElement();
                            String value;
                            try {
                                value = sub.getStringValue(valueName);
                                if (getValue("valor").compareTo(value) == 0) {
                                    _resultados.add(new Parametro("clave", sub.getFullName() + ":" + value));

                                }
                            } catch (Exception exc) {
                                //exc.printStackTrace();
                            }
                        }

                        if (iteracion == 2) {
                            buscarValorRegistro(clave + "\\" + nueva_clave, raiz, 2);
                        }
                        if (iteracion == 1) {
                            buscarValorRegistro(clave + nueva_clave, raiz, 2);
                        }

                    }
                }
            }
        } catch (RegistryException ex) {
            ex.printStackTrace();
        }
    }
}

